package spring.cloud.tasks.tasks_manager.taskInstanceManager;

import spring.cloud.tasks.tasks_manager.schedule.TaskInstanceInfo;
import spring.cloud.tasks.tasks_manager.schedule.TaskInstanceInfoContext;

import java.util.Comparator;
import java.util.Date;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.CopyOnWriteArrayList;

public class TaskInstanceManager {


    public static class TaskInstanceMatrix {
        /**
         * 任务更新版本为key,value为任务实例id
         */
        ConcurrentSkipListMap<Long, CopyOnWriteArrayList<TaskInstanceInfo>> updateVersionToTaskInstanceInfoListMap = new ConcurrentSkipListMap<Long, CopyOnWriteArrayList<TaskInstanceInfo>>(new Comparator<Long>() {
            @Override
            public int compare(Long o1, Long o2) {
                return o1.compareTo(o2);//越小的在前面
            }
        });
    }

    public ConcurrentHashMap<String, TaskInstanceMatrix> taskIdToTaskInstanceMatrixMap = new ConcurrentHashMap<>();

    public CopyOnWriteArrayList<TaskInstanceInfo> get(String taskId, Long updateVersion) {

        taskIdToTaskInstanceMatrixMap.putIfAbsent(taskId, new TaskInstanceMatrix());
        TaskInstanceMatrix taskInstanceMatrix = taskIdToTaskInstanceMatrixMap.get(taskId);
        ConcurrentSkipListMap<Long, CopyOnWriteArrayList<TaskInstanceInfo>> updateVersionToTaskInstanceInfoListMap = taskInstanceMatrix.updateVersionToTaskInstanceInfoListMap;
        updateVersionToTaskInstanceInfoListMap.put(updateVersion, new CopyOnWriteArrayList<TaskInstanceInfo>());
        CopyOnWriteArrayList<TaskInstanceInfo> taskInstanceInfoList = updateVersionToTaskInstanceInfoListMap.get(updateVersion);
        return taskInstanceInfoList;
    }

    public Comparator<TaskInstanceInfo> createTaskInstanceInfoListComparator() {
        Comparator<TaskInstanceInfo> comparator = new Comparator<TaskInstanceInfo>() {
            @Override
            public int compare(TaskInstanceInfo o1, TaskInstanceInfo o2) {
                long l1 = Long.parseLong(o1.getTaskInstanceId());
                long l2 = Long.parseLong(o2.getTaskInstanceId());
                return Long.valueOf(l1).compareTo(Long.valueOf(l2));
            }
        };
        return comparator;
    }

    public void tryCancel(String taskId, long updateVersion) {

        TaskInstanceMatrix taskInstanceMatrix = taskIdToTaskInstanceMatrixMap.get(taskId);
        if (taskInstanceMatrix == null) {
            return;
        }
        ConcurrentSkipListMap<Long, CopyOnWriteArrayList<TaskInstanceInfo>> updateVersionToTaskInstanceInfoListMap = taskInstanceMatrix.updateVersionToTaskInstanceInfoListMap;
        if (updateVersionToTaskInstanceInfoListMap == null) {
            return;
        }
        Set<Long> updateVersionSet = updateVersionToTaskInstanceInfoListMap.keySet();
        Date nowDate = new Date();
        for (Long updateVersion2 : updateVersionSet) {
            if (updateVersion2 < updateVersion) {
                CopyOnWriteArrayList<TaskInstanceInfo> taskInstanceInfoList = updateVersionToTaskInstanceInfoListMap.get(updateVersion2);
                if (taskInstanceInfoList != null) {
                    for (TaskInstanceInfo taskInstanceInfo : taskInstanceInfoList) {
                        if (nowDate.getTime() <= taskInstanceInfo.getNextFireDate().getTime()) {
                            taskInstanceInfo.tryCancel = true;//通知后面调度的程序不用再进行预调度和执行了，如果任务实例完成，那么则不用处理了。
                            taskInstanceInfo.tryCancelDate = nowDate;
                        }
                    }
                }
            }
        }
        updateVersionToTaskInstanceInfoListMap.put(updateVersion, new CopyOnWriteArrayList<TaskInstanceInfo>());
        CopyOnWriteArrayList<TaskInstanceInfo> taskInstanceInfoList = updateVersionToTaskInstanceInfoListMap.get(updateVersion);

    }

    public ConcurrentHashMap<String, Long> taskIdToUpdateVersionMap = new ConcurrentHashMap<String, Long>();
    //
    //
    public ConcurrentHashMap<String, ConcurrentHashMap<String, CopyOnWriteArrayList<TaskInstanceInfo>>> tasks = new ConcurrentHashMap<String, ConcurrentHashMap<String, CopyOnWriteArrayList<TaskInstanceInfo>>>();
    public ConcurrentHashMap<String, TaskInstanceInfoContext> taskIdToTaskInstanceInfoContextMap = new ConcurrentHashMap<>();
    /**
     * 待运行的批次任务实例信息
     */
    public ConcurrentHashMap<String, CopyOnWriteArrayList<TaskInstanceInfo>> waitingAssignTasks = new ConcurrentHashMap<String, CopyOnWriteArrayList<TaskInstanceInfo>>();
    /**
     * 正在运行的批次任务实例信息
     */
    public ConcurrentHashMap<String, CopyOnWriteArrayList<TaskInstanceInfo>> assignedTasks = new ConcurrentHashMap<String, CopyOnWriteArrayList<TaskInstanceInfo>>();

}
